package org.file5.domain;

import java.io.Serializable;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;

import javax.persistence.Id;
import javax.persistence.PrePersist;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.compass.annotations.SearchableId;

import com.google.appengine.repackaged.com.google.common.util.Base64;
import com.googlecode.objectify.annotation.Cached;

@Cached
public class BaseEntity implements Serializable {

	private static String previousMd5Seed = "83*y3#$7ds9&96^as肥猫";
	private static String currentMd5Seed = "83*y3#$7ds9&96^as肥猫";
	/**
	 * 
	 */
	private static final long serialVersionUID = -4998236924688588871L;

	@Id
	@SearchableId
	protected String uid;

	protected Date created;

	protected Date lastUpdated;
	protected STATUS status;
	protected Date statusUpdated;
	// -------------BaseEntity Fields------------

	public BaseEntity() {
	}

	public String getUid() {
		return uid;
	}

	public void setUid(String uid) {
		this.uid = uid;
	}

	public Date getCreated() {
		return created;
	}

	public void setCreated(Date created) {
		this.created = created;
	}

	public Date getLastUpdated() {
		return lastUpdated;
	}

	public void setLastUpdated(Date lastUpdated) {
		this.lastUpdated = lastUpdated;
	}

	public STATUS getStatus() {
		return status;
	}

	public void setStatus(STATUS status) {
		this.status = status;
	}


	public boolean isNew() {
		return (this.uid == null || "".equals(uid));
	}


	public Date getStatusUpdated() {
		return statusUpdated;
	}

	public void setStatusUpdated(Date statusUpdated) {
		this.statusUpdated = statusUpdated;
	}

	// to prevent some important fields being updated by counter or other sites
	public String getComputedMd5() {
		return this.getComputedMd5(uid);
	}

	public String getComputedMd5(String... params) {

		String digestStr = null;
		StringWriter sw = new StringWriter();
		if (params != null) {
			for (String s : params) {
				sw.append(s);
			}
			MessageDigest messageDigest;
			try {
				messageDigest = MessageDigest.getInstance("MD5");
				messageDigest.update(sw.append(currentMd5Seed).toString()
						.getBytes());
				// String digestedPwdString = new
				// String(messageDigest.digest());
				digestStr = new String(Base64.encode(messageDigest.digest()));
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return digestStr;
	}

	@PrePersist
	private void PrePersist() {
		lastUpdated = Calendar.getInstance().getTime();
		;
		if (created == null) {
			created = Calendar.getInstance().getTime();
		}
//		md5 = this.getComputedMd5();
	}

	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE);
	}

	public static enum STATUS {
		// Entity Property Name
		// ---------------------------------------------------------------------------------------------------

		ONLINE(0, "entity is online"), OFFLINE(1, "entity is offline"),

		; // ----------------------------------------------------------------------------------------------------------------

		Integer id;

		String desc;

		STATUS(Integer id, String desc) {
			this.id = id;
			this.desc = desc;
		}

		public Integer getId() {
			return id;
		}

		public void setId(Integer id) {
			this.id = id;
		}

		public String getDesc() {
			return desc;
		}

	}

}
